/*
 * sht20.c
 *
 *  Created on: May 23, 2023
 *      Author: Terrell
 */
#if 0
#include<stdio.h>
#include"stm32l4xx_hal.h"
#include"i2c.h"
#include"sht20.h"

//#define CONFIG_SHT20_DEBUG

#ifdef CONFIG_SHY20_DEBUG
#define sht20_print(format,args...) printf(format,##args)
#else
#define sht20_print(format,args...) do{} while(0)
#endif

static int shy20_send_cmd(SHT20_CMD cmd)
{
   uint8_t buf[2];
   buf[0]=cmd>>8;
   buf[1]=cmd&0xFF;
   return HAL_I2C_Master_Transmit(&hi2c2,SHT20_ADDR_WR,(uint8_t *)buf,2,0xFFFF);

}

static void sht20_soft_reset(void)
{
  sht20_send_cmd(SOFT_RESET_CMD);
  HAL_Delay(1);

}

static int sht20_single_shot_measurement(uint8_t *buf,uint8_t nuf_size)
{
  uint16_t cmd=HIGH_ENABLED_CMD;
  uint8_t rv;

  if(!buf||buf_size<SHT20_DATA_SIZE)
  {
	  sht30_print("%s():Invalid input arguments\n",__func__);
	  return -1;
  }

  rv=sht20_send_cmd(cmd);
  if(rv)
  {
	  sht20_print("ERROR:SHT30 read measurement result failure,rv=%d\n",rv);
	  return -3;

  }
  return 0;
}

static uint8_t sht20_crc8(const uint8_t *data,int len)
{
  const uint8_t POLYNOMIAL=0x31;
  uint8_t crc=0xFF;
  int i,j;

  for(i=0;i<len;++i)
  {
	  crc^=*data++;
	  for(j=0;j<8;++j)
	  {
		  crc=(crc&0x80)?(crc<<1)^POLYNOMIAL:(crc<<1);

	  }

  }

  return crc;
}

int SHT20_SampleData(float *temperature,float *humidity)
{
  uint8_t buf[SHT20_DATA_SIZE];
  int rv;
  uint16_t temp;
  uint16_t humd;
  uint8_t crc;

  if(!temperature||!humidity)
  {
	  sht20_print("%s():Invalid input arguments\n",__func__);
	  return -1;
  }

  rv=sht30_single_shot_measurement(buf,SHT20_DATA_SIZE);

  if(rv)
  {
	  sht20_print("SHT20 Single short measurement failure,rv=%d\n",rv);
	  return -2;

  }

#ifdef CONFIG_SHT20_DEBUG
  {
	  int i;
	  sht20_print("SHT20 get %d bytes sample data:\n",SHT20_DATA_SIZE);
	  for(i=0;i<SHT20_DATA_SIZE;i++)
	  {
		  sht20_print("0x%02x",buf[i])

	  }
	  sht20_print("\n");
  }
#endif

  /* byte[0-1] is temperature value,and byte[2] is temperature CRC*/
  crc=sht20_crc8(buf,2);
  sht20_print("SHT20 temperature Cal_CRC:[%02x] EXP_CRC:[%02x]\n",crc,buf[2]);
  if(crc!=buf[2])
  {
	  sht20_print("SHT20 measurement temperature got CRC error\n");
	  return -3;

  }

  /*byte[3-4] is humidity value,and byte[5] is humidity CRC*/
  crc=sht20_crc8(&buf[3],2);
  sht20_print("SHT20 humidity Cal_CRC:[%02X] EXP_CRC:[%02x]\n",crc,buf[5]);
  if(crc!=buf[5])
  {
	  sht20_print("SHT20 measurement temperature got CRC error\n");
	  return -4;

  }

  temp=(buf[0]<<8)|buf[1];
  humd=(buf[3]<<8)|buf[4];

  *temperature=-45+175*((float)temp/65535);
  *humidity=100*((float)humd/65535);

  return 0;

}
#endif

#include "sht20.h"
#include <stdio.h>
#include <string.h>
#include "stm32l4xx_hal.h"


#define CONFIG_GPIO_I2C

#ifdef CONFIG_GPIO_I2C
#include "gpio_i2c_sht20.h"
#else
#include" i2c.h"
#endif


#define delay_ms(x)		HAL_Delay(x)

#define CONFIG_SHT2X_DEBUG

#ifdef CONFIG_SHT2X_DEBUG
static inline void dump_buf(uint8_t *buf, uint32_t size)
{
	int i;

	if(!buf)
		return ;

	for(i=0; i<size; i++)
		printf("%02x ", buf[i]);

	printf("\r\n");
}
#endif

#ifdef CONFIG_SHT2X_DEBUG
#define sht2x_print(format,args...) printf(format, ##args)
#else
#define sht2x_print(format,args...) do{} while(0);
#endif


static int sht2x_measure_value(uint8_t command, uint16_t *val);
static int sht2x_softreset(void);
static int sht2x_checkcrc(uint8_t *data, uint8_t bytes, uint8_t checksum);

uint32_t sht20_sample_TrH(uint32_t *temperature, uint32_t *humidity)
{
	uint16_t       sT;
	uint16_t       sRH;
	uint32_t       T;
	uint32_t       RH;
	uint32_t       TRH=TRH_FAIL_VAL;

//	i2c_term(SHT2X_I2CBUS);
//
//	if( i2c_init(SHT2X_I2CBUS, SHT2X_CHIPADDR) )
//	{
//		sht2x_print("SHT20 initial I2C bus failed.\r\n");
//		return TRH;
//	}

	if( sht2x_softreset() )
	{
		sht2x_print("SHT20 soft reset failed.\r\n");
		goto OUT;
	}

	sht2x_print("Start to measurement temperature...\r\n");
	if( sht2x_measure_value(TRIG_T_MEASUREMENT_POLL, &sT) < 0 )
	{
		sht2x_print("I2C measurement failed\r\n");
		goto OUT;
	}

	T=(uint32_t)(100*(float)((175.72*sT)/65536-46.85));
	sht2x_print("Measure temperature: %lu.%lu\r\n", T/100, T%100);
	if( temperature )
		*temperature=T;

	TRH = ((T/100)<<8|(T%100))<<16 | 0xFFFF;

	sht2x_print("Start to measurement relative humidity...\r\n");
	if( sht2x_measure_value(TRIG_RH_MEASUREMENT_POLL, &sRH) < 0 )
	{
		goto OUT;
	}

	RH=(uint32_t)(100*(float)((125.0*sRH)/65535-6.0));
	sht2x_print("Measure relative humidity: %lu.%lu%%\r\n", RH/100, RH%100);
	if( humidity )
		*humidity=RH;

	TRH &=  0xFFFF0000 | ((uint16_t)RH/100)<<8 | ((uint16_t)RH%100) ;

	OUT:
//	i2c_term(SHT2X_I2CBUS);
	return TRH;
}

int sht2x_softreset(void)
{
	uint8_t           command = SOFT_RESET;
	int               rv = 0;

	sht2x_print("Start soft reset sht2x\r\n");
//	rv=i2c_write(SHT2X_I2CBUS, &command, 1);
#if 0
	rv = HAL_I2C_Master_Transmit(&hi2c1, SHT20_ADDR_WR, &command, 1, 0xFFFF);
#endif
	rv=I2C_Master_Transmit(SHT20_ADDR_WR,&command,1);
	if( rv )
	{
		sht2x_print("SHT2X send soft reset command 0x%0x failure: rv=0x%02x\r\n", command, rv);
		return -rv;
	}

	delay_ms(15);
	return 0;
}

static int sht2x_checkcrc(uint8_t *data, uint8_t bytes, uint8_t checksum)
{
  uint8_t crc = 0;
  uint8_t i;
  uint8_t bit;

  //calculates 8-Bit checksum with given polynomial
  for (i=0; i<bytes; ++i)
  {
    crc ^= (data[i]);
    for (bit=8; bit>0; --bit)
    {
      if (crc & 0x80)
        crc = (crc << 1) ^ 0x0131; //POLYNOMIAL;
      else
        crc = (crc << 1);
    }
  }

  if (crc != checksum)
  {
    return -1;
  }
  else
  {
    return 0;
  }
}

static int sht2x_measure_value(uint8_t command, uint16_t *val)
{
	uint8_t        buf[3];    /* I2C������buffer */
	int            count=4;    /* �ܹ����Ĵ��� */

	if( !val )
	{
		sht2x_print("SHT2X invalid input arguments\r\n");
		return -1;
	}

	if(TRIG_T_MEASUREMENT_POLL!=command && TRIG_RH_MEASUREMENT_POLL !=command )
	{
		sht2x_print("SHT2X unsupport command: 0x%0x\r\n", command);
		return -2;
	}




//	if( NO_ERROR != i2c_write(SHT2X_I2CBUS, &command, 1) )
	if( I2C_Master_Transmit(SHT20_ADDR_WR,&command,1) )     //HAL_I2C_Master_Transmit(&hi2c1, SHT20_ADDR_WR, &command, 1, 0xFFFF)
	{
		sht2x_print("SHT2X send measure command 0x%0x failure\r\n", command);
		return -3;
	}

	if(TRIG_T_MEASUREMENT_POLL == command)
		delay_ms(85);
	else
		delay_ms(29);

	while(count--)
	{
		memset(buf, 0, 3);

//		if( !i2c_read(SHT2X_I2CBUS, buf, 3) )
		if( !I2C_Master_Receive(SHT20_ADDR_RD,buf, 3) )    //!HAL_I2C_Master_Receive(&hi2c1, SHT20_ADDR_RD, buf, 3, 0xFFFF)
		{
			break;
		}
		delay_ms(5);
	}

	if( sht2x_checkcrc(buf, 2, buf[2])< 0 )
	{
#ifdef CONFIG_SHT2X_DEBUG
		sht2x_print("Measurement data checksum failure:\r\n");
		dump_buf(buf, 3);
#endif
		return -4;
	}

	if(TRIG_T_MEASUREMENT_POLL == command)
		*val = buf[0]<<8|(buf[1]&0xFC); //14bits(1111 1100)
	else
		*val = buf[0]<<8|(buf[1]&0xF0); //12bits(1100 0000)

	sht2x_print("Measurement temperature value: 0x%04x\r\n", *val);

  return 0;
}







